/*
 * Copyright (c) 2007
 *	Alberto Magni, Maggioni Marcello
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
package Database.XMLManager;

import exceptions.DatabaseException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;

/**
 *  This file represents a file that stores informations in XML format
 * 
 * @author Marcello Maggioni
 */
abstract public class XMLFile extends File {

    private Document doc = null;
    private DocumentBuilder docbuild = null;
    private StreamResult sr = null;
    private Transformer transformer = null;
    
    /**
     * Constructs and instance of XMLFile
     * 
     * @param filename The path of the file
     * @throws javax.xml.parsers.ParserConfigurationException
     * @throws javax.xml.transform.TransformerConfigurationException
     * @throws exceptions.DatabaseException
     */
    protected XMLFile(String filename) throws ParserConfigurationException, TransformerConfigurationException, DatabaseException {
        super(filename);
        sr = new StreamResult(this);
        docbuild = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        transformer = TransformerFactory.newInstance().newTransformer();
    }
/**
 * This method returns an InputStream object used to directly read from the file
 * 
 * @return An InputStream object
 * @throws exceptions.DatabaseException
 */
    protected InputStream getInputStream() throws DatabaseException {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(this);
        } catch (FileNotFoundException ex) {
            throw new DatabaseException(ex.getMessage());
        }

        return fis;
    }
/**
 * This method returns a Document object representing the contents of the XML file
 * 
 * @return A Document object with the contents of the file
 * @throws exceptions.DatabaseException
 */
    protected Document readFile() throws DatabaseException {

        try {
            if (doc == null) {
                doc = docbuild.parse(this); // Read the file only for the first time.
            }
            return doc;
        } catch (Exception ex) {
            throw new DatabaseException(ex.getMessage());
        }
    }
/**
 * This method writes the Document object specified as parameter to file
 *  
 * @param d A Document object
 * @throws exceptions.DatabaseException
 */
    protected void writeFile(Document d) throws DatabaseException {
        try {
            transformer.transform(new DOMSource(d), sr);
            doc = d;
        } catch (Exception ex) {
            throw new DatabaseException(ex.getMessage());
        }
    }
/**
 * This method initializes the file to a black document
 * 
 * @throws exceptions.DatabaseException
 */
    protected void initialize() throws DatabaseException {
        try {
            String parent = getParent();
            File dir = new File(parent);
            dir.mkdirs();
            if(!exists())
                createNewFile();
            Document d = docbuild.newDocument();
            writeFile(d);
        } catch (IOException ex) {
            throw new DatabaseException(ex.getMessage());
        }
    }
}
